#include "wifi.h"
#include <stdlib.h>
#include "net_api.h"
#include "stm32f1xx_hal.h"
#include "string.h"
#include "uart.h"

const sNet wifi_netapi = {Wifi_Connect_Server, Wifi_DisConnect, Wifi_SendData,
                          Wifi_GetIPD, Wifi_ClearRecive};

uint8_t Wifi_WaitRecive(void) {
  uint16_t len = uart_getlen();
  if (len > 0) {
    Net_IO.dataLen = len;
  }
  if (Net_IO.dataLen ==
      0) {  //如果接收计数为0 则说明没有处于接收数据中，所以直接跳出，结束函数
    return WIFI_REV_WAIT;
  }
  if (Net_IO.dataLen ==
      Net_IO.dataLenPre) {  //如果上一次的值和这次相同，则说明接收完毕
    if ((strlen((const char *)Net_IO.buf) + Net_IO.dataLen) > 512) {
      Net_IO.dataLen = 511 - strlen((const char *)Net_IO.buf);
    }
    uart_receive(&Net_IO.buf[strlen((const char *)Net_IO.buf)], Net_IO.dataLen);
    Net_IO.dataLen = 0;  //清0接收计数
    return WIFI_REV_OK;  //返回接收完成标志
  }
  Net_IO.dataLenPre = Net_IO.dataLen;  //置为相同
  return WIFI_REV_WAIT;                //返回接收未完成标志
}

void Wifi_ClearRecive(void) {
  Net_IO.dataLen = 0;
  Net_IO.dataLenPre = 0;
  memset(Net_IO.buf, 0, sizeof(Net_IO.buf));
}

uint8_t Wifi_SendCmd(char *cmd, char *res) {
  uint8_t timeOut = 250;
  Wifi_ClearRecive();
  uart_send((uint8_t *)cmd, strlen((const char *)cmd));  //写命令到网络设备
  while (timeOut--) {                                    //等待
    if (Wifi_WaitRecive() == WIFI_REV_OK) {              //如果收到数据
      if (strstr((const char *)Net_IO.buf, res) != NULL) {  //如果检索到关键词
        Wifi_ClearRecive();                                 //清空缓存
        return 0;
      }
    }
    HAL_Delay(2);  //挂起等待
  }
  return 1;
}

void Wifi_QuitTrans(void) {
  static uint8_t sim = '+';
  uart_send(&sim, 1);
  HAL_Delay(3);  //大于串口组帧时间(10ms)

  uart_send(&sim, 1);
  HAL_Delay(3);  //大于串口组帧时间(10ms)

  uart_send(&sim, 1);
  HAL_Delay(20);  //等待100ms

  Wifi_SendCmd("AT+CIPMODE=0\r\n", "OK");  //关闭透传模式
}

void Wifi_EnterTrans(void) {
  Wifi_SendCmd("AT+CIPMUX=0\r\n", "OK");  //单链接模式

  Wifi_SendCmd("AT+CIPMODE=1\r\n", "OK");  //使能透传

  Wifi_SendCmd("AT+CIPSEND\r\n", ">");  //发送数据

  HAL_Delay(20);  //等待100ms
}

unsigned char Wifi_Reset(void) { return Wifi_SendCmd("AT+RST\r\n", "OK"); }

void Wifi_SendData(unsigned char *data, int len) {
  char cmdBuf[30];
  HAL_Delay(1);  //等待一下

  Wifi_ClearRecive();                         //清空接收缓存
  sprintf(cmdBuf, "AT+CIPSEND=%d\r\n", len);  //发送命令
  // if(!NET_DEVICE_SendCmd(cmdBuf, ">"))
  // //收到‘>’时可以发送数据
  if (Wifi_SendCmd(cmdBuf, ">") == 0) {
    uart_send(data, len);  //发送设备连接请求数据
  }

  uart_send(data, len);
}

unsigned char *Wifi_GetIPD(unsigned int timeOut) {
  uint8_t byte = 0, count = 0;
  char sByte[5];
  char *ptrIPD;

  do {
    if (Wifi_WaitRecive() == WIFI_REV_OK) {         //如果接收完成
      ptrIPD = strstr((char *)Net_IO.buf, "IPD,");  //搜索“IPD”头
      if (ptrIPD !=
          NULL) {  //如果没找到，可能是IPD头的延迟，还是需要等待一会，但不会超过设定的时间
        ptrIPD = strstr(ptrIPD, ",");
        ptrIPD++;  //找到','  ，然后偏移到下一个字符，代表数据长度的第一个数字
        while (*ptrIPD != ':') {  //在','和':' 之间的都是数据长度的数据
          sByte[count++] = *ptrIPD++;
        }
        byte = (unsigned char)atoi(sByte);  //将字符转为数值形式

        ptrIPD++;  //此时ptrIPD指针还指向':'，所以需要偏移到下个数据
        for (count = 0; count < byte; count++) {  //复制数据
          Net_IO.buf[count] = *ptrIPD++;
        }
        memset(Net_IO.buf + byte, 0,
               sizeof(Net_IO.buf) - byte);  //将后边的数据清空
        return Net_IO.buf;                  //复制完成，返回数据指针
      }
    }

    HAL_Delay(2);  //延时等待
  } while (timeOut--);

  return NULL;  //超时还未找到，返回空指针
}

unsigned char Wifi_Connect(void) {
  uint8_t status = 0;

  status = Wifi_SendCmd(AT_CIPSTART, AT_CIPSTART_RES);  //重新连接

  return status;
}

unsigned char Wifi_Connect_Server(char *ip, unsigned int port) {
  uint8_t status = 0;
  static char str[64] = {0};
  sprintf(str, "AT+CIPSTART=\"TCP\",\"%d.%d.%d.%d\",%d,50\r\n", ip[0], ip[1],
          ip[2], ip[3], port);
  status = Wifi_SendCmd(str, AT_CIPSTART_RES);

  return status;
}

unsigned char Wifi_ReConnect(void) {
  uint8_t status = 0;

  Wifi_SendCmd(AT_CIPCLOSE, AT_CIPCLOSE_RES);  //连接前先关闭一次
  HAL_Delay(100);                              //等待
  status = Wifi_SendCmd(AT_CIPSTART, AT_CIPSTART_RES);  //重新连接

  return status;
}

unsigned char Wifi_DisConnect(void) {
  uint8_t status = 0;

  status = Wifi_SendCmd(AT_CIPCLOSE, AT_CIPCLOSE_RES);  //断开连接

  return status;
}

void Wifi_Check(void) {
  Wifi_ClearRecive();
  uart_send((uint8_t *)AT_STATUS, strlen(AT_STATUS));
}

eWifiInfo Wifi_CheckNet(void) {
  eWifiInfo status = Wifi_None;
  unsigned char timeOut = 200;

  Wifi_ClearRecive();
  uart_send((uint8_t *)"AT+CIPSTATUS\r\n",
            strlen("AT+CIPSTATUS\r\n"));  //写命令到网络设备
  while (timeOut--) {                     //等待
    if (Wifi_WaitRecive() == WIFI_REV_OK) {
      if (strstr((const char *)Net_IO.buf, "STATUS:2") != NULL) {
        status = Wifi_GoTIP;
      } else if (strstr((const char *)Net_IO.buf, "STATUS:3") != NULL) {
        status = Wifi_Conn;
      } else if (strstr((const char *)Net_IO.buf, "STATUS:4") != NULL) {
        status = Wifi_DisConn;
      } else if (strstr((const char *)Net_IO.buf, "STATUS:5") != NULL) {
        status = Wifi_Lost;
      }
    }
    HAL_Delay(2);
  }
  return status;
}
